package com.gzhryc.shared_device.oem.code.agent.services;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.oem.code.agent.dao.AgentRelationDao;
import com.gzhryc.shared_device.oem.code.agent.dao.db.Agent;
import com.gzhryc.shared_device.oem.code.agent.dao.db.AgentRelation;
import com.gzhryc.shared_device.oem.code.agent.dao.db.AgentRelationFuncModel;
import com.gzhryc.shared_device.oem.code.agent.dao.models.AgentRelationCount;
import com.gzhryc.shared_device.oem.code.agent.services.dto.AgentRelationDeviceSearch;
import com.gzhryc.shared_device.oem.code.agent.services.dto.AgentRelationSearch;
import com.gzhryc.shared_device.oem.code.agent.services.dto.UserKeySearch;
import com.gzhryc.shared_device.oem.code.config.dao.db.FuncModel;
import com.gzhryc.shared_device.oem.code.config.services.FuncModelService;
import com.gzhryc.shared_device.oem.code.place.dao.db.PlaceProfitUser;
import com.gzhryc.shared_device.oem.code.place.services.PlaceProfitUserService;
import com.gzhryc.shared_device.oem.code.user.dao.db.User;
import com.gzhryc.shared_device.oem.code.user.services.UserService;

public class AgentRelationService {

    static Logger log = Logger.getLogger(AgentRelationService.class);

    public static AgentRelationService self() {
        return MultiDBTools.getService(AgentRelationService.class, true);
    }

    public static AgentRelationService self(String jdbcKey) {
        return MultiDBTools.getService(jdbcKey, AgentRelationService.class, true);
    }

    AgentRelationDao dao;

    public AgentRelationService(String jdbcKey) {
        this.dao = new AgentRelationDao(jdbcKey);
    }

    public List<AgentRelation> findJoinBySearch(AgentRelationSearch search, Integer pageNo, Integer pageLimit) {
        Conditions conditions = dao.buildConditions(search);
        conditions.and().likeBoth("relationUser.name", search.getTrim())
                .or().likeBoth("relationUser.phone", search.getTrim());

        try {
            return dao.findJoinByCondition(conditions, pageNo, pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public Long countJoinBySearch(AgentRelationSearch search){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().likeBoth("relationUser.name", search.getTrim())
                .or().likeBoth("relationUser.phone", search.getTrim());

        try {
            return dao.countJoin(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
        return 0L;
    }

    public List<AgentRelation> findJoinByUserId(Long userId,Integer pageNo,Integer pageLimit){
        if(userId != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId",userId);

            try {
                return dao.findJoinByCondition(conditions,pageNo,pageLimit);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public List<AgentRelation> findByRelationUserId(Long relationUserId){
        if(relationUserId != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("relationUserId",relationUserId);

            try {
                return dao.findByCondition(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public Long countByRelationUserId(Long relationUserId){
        if(relationUserId != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("relationUserId",relationUserId);

            try {
                return dao.count(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return 0L;
    }

    public Long countJoinByUserId(Long userId){
        if(userId != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId",userId);

            try {
                return dao.countJoin(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return 0L;
    }

    public List<AgentRelationCount> findRelationCount(UserKeySearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = new Conditions(AgentRelationCount.class);
        conditions.and().is("user.id",search.getId());
        conditions.and().likeBoth("user.name",search.getName());
        conditions.and().likeBoth("user.phone",search.getPhone());
        try {
            return dao.countGroupUserId(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public Long countRelationCount(UserKeySearch search){
        Conditions conditions = new Conditions(AgentRelationCount.class);
        conditions.and().is("user.id",search.getId());
        conditions.and().likeBoth("user.name",search.getName());
        conditions.and().likeBoth("user.phone",search.getPhone());

        try {
            return dao.countUserId(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return 0L;
    }

    public AgentRelation getByKeys(Long userId,Long relationUserId){
        if (userId != null && relationUserId != null) {
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId", userId);
            conditions.and().is("relationUserId", relationUserId);

            try {
                return dao.get(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public AgentRelation getJoinByKeys(Long userId,Long relationUserId){
        if (userId != null && relationUserId != null) {
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId", userId);
            conditions.and().is("relationUserId", relationUserId);

            try {
                return dao.getJoin(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }
    
    public AgentRelation getLogin(Long userId,Long relationUserId){
        AgentRelation agentRelation = getByKeys(userId,relationUserId);
        if(agentRelation != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId", agentRelation.getUserId());
            conditions.and().is("relationUserId", agentRelation.getRelationUserId());

            AgentRelation updateEntity = new AgentRelation();
            updateEntity.setLastLoginDate(new Date());

            try {
                if(dao.updateNotNull(updateEntity,conditions) <= 0){
                    log.error("修改最后登陆时间失败，用户ID：{{0}}，关联用户ID：{{1}}",userId,relationUserId);
                }
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return agentRelation;
    }

    public AgentRelation getLastLogin(Long relationUserId){
        if(relationUserId != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("relationUserId", relationUserId);
            conditions.desc("lastLoginDate");
            conditions.asc("roleType");
            conditions.asc("createDate");

            try {
                return dao.get(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public AgentRelation getLastLogin(Long relationUserId,Integer roleType){
        if(relationUserId != null && roleType != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("relationUserId",relationUserId);
            conditions.and().is("roleType", roleType);
            conditions.desc("lastLoginDate");

            try {
            	return dao.get(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }
    
    public boolean replaceLastLogin(Long userId,Long relationUserId) {
    	 if (userId != null && relationUserId != null) {
	    	Conditions conditions = new Conditions(AgentRelation.class);
	        conditions.and().is("userId",userId);
	        conditions.and().is("relationUserId", relationUserId);
	
	        AgentRelation updateEntity = new AgentRelation();
	        updateEntity.setLastLoginDate(new Date());
	
	        try {
				if(dao.updateNotNull(updateEntity,conditions) > 0){
					return true;
				}else {
				    log.error("修改最后登陆时间失败，用户ID：{{0}}，关联用户ID：{{1}}",userId,relationUserId);
				}
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
    	}
    	return false;
    }
    
    public boolean add(AgentRelation agentRelation,List<Long> funcModelIds) throws LogicException {
    	AgentRelation temp = getByKeys(agentRelation.getUserId(),agentRelation.getRelationUserId());
        if(temp != null) {
            throw new LogicException("用户已存在");
        }
        Agent agent = AgentService.self().getByUserId(agentRelation.getUserId());
        if(agent == null){
            throw new LogicException("非代理用户不允许添加");
        }
        User user = UserService.self().getById(agentRelation.getRelationUserId());
        if(user == null){
            throw new LogicException("未找到关联用户信息");
        }
        List<AgentRelationFuncModel> agentRelationFuncModelList = null;
        if(funcModelIds != null && funcModelIds.size() > 0){
            List<FuncModel> funcModelList = FuncModelService.self().findByIds(funcModelIds);
            if(funcModelList == null || funcModelList.size() <= 0){
                throw new LogicException("未找到指定功能模块");
            }
            agentRelationFuncModelList = new ArrayList<>();
            for(FuncModel funcModel : funcModelList){
                AgentRelationFuncModel agentRelationFuncModel = new AgentRelationFuncModel();
                agentRelationFuncModel.setUserId(agentRelation.getUserId());
                agentRelationFuncModel.setRelationUserId(agentRelation.getRelationUserId());
                agentRelationFuncModel.setFuncModelId(funcModel.getId());
                agentRelationFuncModel.setCreateDate(new Date());
                agentRelationFuncModelList.add(agentRelationFuncModel);
            }
        }
        agentRelation.setCreateDate(new Date());

        JdbcSession.begin();
        try {
            if(dao.insert(agentRelation) > 0){
                if(agentRelationFuncModelList != null && agentRelationFuncModelList.size() > 0){
                    if(AgentRelationFuncModelService.self().add(agentRelationFuncModelList)) {
                        JdbcSession.commit();
                        return true;
                    }
                }else{
                    JdbcSession.commit();
                    return true;
                }
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        } finally {
            JdbcSession.end();
        }
        return false;
    }

    public boolean add(AgentRelation agentRelation, User user,List<Long> funcModelIds) throws LogicException {
        AgentRelation temp = getByKeys(agentRelation.getUserId(),user.getId());
        if(temp != null) {
            throw new LogicException("用户已存在");
        }
        Agent agent = AgentService.self().getByUserId(agentRelation.getUserId());
        if(agent == null){
            throw new LogicException("非代理用户不允许添加");
        }
        List<AgentRelationFuncModel> agentRelationFuncModelList = null;
        if(funcModelIds != null && funcModelIds.size() > 0){
            List<FuncModel> funcModelList = FuncModelService.self().findByIds(funcModelIds);
            if(funcModelList == null || funcModelList.size() <= 0){
                throw new LogicException("未找到指定功能模块");
            }
            agentRelationFuncModelList = new ArrayList<>();
            for(FuncModel funcModel : funcModelList){
                AgentRelationFuncModel agentRelationFuncModel = new AgentRelationFuncModel();
                agentRelationFuncModel.setUserId(agentRelation.getUserId());
                agentRelationFuncModel.setRelationUserId(user.getId());
                agentRelationFuncModel.setFuncModelId(funcModel.getId());
                agentRelationFuncModel.setCreateDate(new Date());
                agentRelationFuncModelList.add(agentRelationFuncModel);
            }
        }
        agentRelation.setCreateDate(new Date());
        JdbcSession.begin();
        try {
            if(UserService.self().add(user)){
                agentRelation.setRelationUserId(user.getId());
                if(dao.insert(agentRelation) > 0){
                    if(agentRelationFuncModelList != null && agentRelationFuncModelList.size() > 0){
                        if(AgentRelationFuncModelService.self().add(agentRelationFuncModelList)) {
                            JdbcSession.commit();
                            return true;
                        }
                    }else{
                        JdbcSession.commit();
                        return true;
                    }
                }
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }finally {
            JdbcSession.end();
        }
        return false;
    }

    public boolean updateRoleType(Long userId,Long relationUserId,Integer roleType) throws LogicException {
    	if(userId != null && relationUserId != null && roleType != null) {
    		AgentRelation agentRelation = this.getByKeys(userId,relationUserId);
    		if(agentRelation == null) {
    			throw new LogicException("未找到用户关系信息");
    		}else if(agentRelation.getRoleType().equals(roleType)) {
    			return true;
    		}
    		Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId", userId);
            conditions.and().is("relationUserId", relationUserId);

            AgentRelation updateEntity = new AgentRelation();
            updateEntity.setRoleType(roleType);

            JdbcSession.begin();
            try {
                if (dao.updateNotNull(updateEntity, conditions) > 0) {
                	if(AgentRelationDeviceService.self().deleteByUsers(userId,relationUserId)) {
                    	if(AgentRelationBusinessConfigService.self().deleteByUsers(userId,relationUserId)) {
	                    	if(AgentRelationFuncModelService.self().deleteByUsers(userId,relationUserId)) {
	                    		JdbcSession.commit();
	                            return true;
	                    	}
                    	}
                	}
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            } finally {
                JdbcSession.end();
            }
    	}
    	return false;
    }
    
    public boolean updateNote(Long userId,Long relationUserId,String note) throws LogicException {
    	if(userId != null && relationUserId != null) {
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId", userId);
            conditions.and().is("relationUserId",relationUserId);

            AgentRelation updateEntity = new AgentRelation();
            updateEntity.setNote(note);

            try {
                if (dao.updateNotNull(updateEntity, conditions, "note") > 0) {
                    return true;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public boolean updatePower(AgentRelation agentRelation) throws LogicException {
    	if(agentRelation != null && agentRelation.getUserId() != null && agentRelation.getRelationUserId() != null) {
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId", agentRelation.getUserId());
            conditions.and().is("relationUserId",agentRelation.getRelationUserId());

            AgentRelation updateEntity = new AgentRelation();
            updateEntity.setCanUndeployDevice(agentRelation.getCanUndeployDevice());

            try {
                if (dao.updateNotNull(updateEntity, conditions) > 0) {
                    return true;
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public void refresh(Long userId) {
        if(userId != null){
            List<AgentRelation> agentRelationList = null;
            try {
                Conditions conditions = new Conditions(AgentRelation.class);
                conditions.and().is("userId",userId);

                agentRelationList = dao.findByCondition(conditions);
                if(agentRelationList != null && agentRelationList.size() > 0){
                    List<Long> relationUserIds = new ArrayList<>();
                    for(AgentRelation agentRelation : agentRelationList){
                        relationUserIds.add(agentRelation.getRelationUserId());
                    }
                    List<User> relationUserList = UserService.self().findByUserIds(relationUserIds);

                    for(AgentRelation agentRelation : agentRelationList){
                        boolean flag = true;
                        if(relationUserList != null && relationUserList.size() > 0){
                            for(User user : relationUserList){
                                if(user.getId().equals(agentRelation.getRelationUserId())){
                                    flag = false;
                                    break;
                                }
                            }
                        }

                        if(flag){
                        	log.info("{{0}}用户已经不存在，删除关系", agentRelation.getRelationUserId());
                            faceDeleteByKeys(agentRelation.getUserId(),agentRelation.getRelationUserId());
                        }
                    }
                }
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
    }

    public boolean deleteByKeys(Long userId,Long relationUserId)throws LogicException {
        if (userId != null && relationUserId != null) {
            AgentRelation agentRelation = getByKeys(userId,relationUserId);
            if(agentRelation == null){
                throw new LogicException("用户关系不存在");
            }

            AgentRelationDeviceSearch deviceSearch = new AgentRelationDeviceSearch();
            deviceSearch.setUserId(userId);
            deviceSearch.setRelationUserId(relationUserId);
            Long deviceCount = AgentRelationDeviceService.self().countJoinBySearch(deviceSearch);
            if(deviceCount != null && deviceCount > 0){
                throw new LogicException("分派了设备，请先移除");
            }

            Long placeCount = PlaceProfitUserService.self().countByUserKeys(userId,relationUserId);
            if(placeCount != null && placeCount > 0){
                throw new LogicException("存在网点关系，请先移除");
            }

            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId", userId);
            conditions.and().is("relationUserId", relationUserId);

            try {
                return dao.deleteByCondition(conditions) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public boolean faceDeleteByKeys(Long userId,Long relationUserId){
        if(userId != null && relationUserId != null) {
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId", userId);
            conditions.and().is("relationUserId",relationUserId);

            JdbcSession.begin();
            try {
                if (dao.deleteByCondition(conditions) > 0) {
                    if(AgentRelationDeviceService.self().deleteByUsers(userId,relationUserId)) {
                    	if(AgentRelationBusinessConfigService.self().deleteByUsers(userId,relationUserId)) {
	                    	if(AgentRelationFuncModelService.self().deleteByUsers(userId,relationUserId)) {
		                        boolean flag = true;
		                        List<PlaceProfitUser> placeProfitUserList = PlaceProfitUserService.self().findByUserKeys(userId, relationUserId);
		                        if (placeProfitUserList != null && placeProfitUserList.size() > 0) {
		                            for(PlaceProfitUser placeProfitUser : placeProfitUserList) {
		                                if(!PlaceProfitUserService.self().deleteByKeys(placeProfitUser.getPlaceId(),placeProfitUser.getUserId())){
		                                    flag = false;
		                                    break;
		                                }
		                            }
		                        }
		
		                        if(flag){
		                            JdbcSession.commit();
		                            return true;
		                        }
                    		}
                    	}
                    }
                }
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            } catch (LogicException e) {
                log.error(e.getMessage(), e);
            } finally {
                JdbcSession.end();
            }

            log.error("强制删除用户关系失败，用户ID：{{0}}，关系用户ID：{{1}}", userId, relationUserId);
        }
        return false;
    }

    public boolean faceDeleteByUserId(Long userId){
        if(userId != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("userId",userId);

            try {
                return dao.deleteByCondition(conditions) >= 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public boolean faceDeleteByRelationUserId(Long relationUserId){
        if(relationUserId != null){
            Conditions conditions = new Conditions(AgentRelation.class);
            conditions.and().is("relationUserId",relationUserId);

            try {
                return dao.deleteByCondition(conditions) >= 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }
}
